﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Xunit;

namespace Fadd.JSON.Test
{
	/// <summary>
	/// Subscribe on an event.
	/// </summary>
	[Serializable]
	public class Subscribe
	{
		/// <summary>
		/// Gets or sets requested event.
		/// </summary>
		public Event Event { get; set; }

		/// <summary>
		/// Gets or sets subscribe or unsubscribe.
		/// </summary>
		public bool Activate { get; set; }

		[Fact]
		private void Test()
		{
			Serializer serializer = new Serializer();
			StringBuilder sb = new StringBuilder();
			TextWriter writer = new StringWriter(sb);
			serializer.Serialize(writer, new Subscribe { Event = Event.Presence });

			Stream stream = new MemoryStream();
			byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
			stream.Write(bytes, 0, bytes.Length);
			stream.Seek(0, SeekOrigin.Begin);

			Deserializer deserializer = new Deserializer();
			Subscribe test = (Subscribe)deserializer.Deserialize(stream, typeof(Subscribe));
		}

		[Fact]
		private void Test2()
		{
			string temp = @"{
  ""ContainedObject"": {
    ""Event"": ""Presence"",
    ""Activate"": true
  }
}";
			StringReader reader = new StringReader(temp);
			Deserializer deserializer = new Deserializer();
			Subscribe test = (Subscribe)deserializer.Deserialize(reader, typeof(Subscribe));

		}



		[Fact]
		private static void Test3()
		{
			EventPacket eventPacket = new EventPacket { ContainedObject = new Subscribe { Activate = true, Event = Event.Presence } };

			StringBuilder sb = new StringBuilder();
			TextWriter writer = new StringWriter(sb);
			Serializer serializer = new Serializer();
			serializer.Serialize(writer, eventPacket);

			string objectString = sb.ToString();

			int length = Encoding.UTF8.GetByteCount(objectString);
			byte[] buffer = new byte[sizeof(int) + length];
			System.Buffer.BlockCopy(BitConverter.GetBytes(length), 0, buffer, 0, sizeof(int));
			Encoding.UTF8.GetBytes(objectString, 0, length, buffer, sizeof(int));


			Deserialize(0, buffer.Length, buffer, 0);
		}

		private static void Deserialize(int _totalLength, int bytesRead, byte[] ReadBuffer, int _receivedLength)
		{
			if (_totalLength == 0)
			{
				_totalLength = BitConverter.ToInt32(ReadBuffer, 0);
				if (_totalLength > ReadBuffer.Length)
				{
					return;
				}
				bytesRead -= 4;
				Buffer.BlockCopy(ReadBuffer, 4, ReadBuffer, 0, bytesRead);
			}

			_receivedLength += bytesRead;
			if (_receivedLength < _totalLength)
			{
				return;

			}

			EventPacket eventPacket;
			using (MemoryStream stream = new MemoryStream(ReadBuffer, 0, _totalLength))
			{
				Deserializer deserializer = new Deserializer();
				eventPacket = (EventPacket)deserializer.Deserialize(stream, typeof(EventPacket));
			}
		}
	}

	/// <summary>
	/// JSON packet.
	/// </summary>
	[Serializable]
	public class EventPacket
	{
		/// <summary>
		/// Gets or sets object being transported.
		/// </summary>
		public object ContainedObject { get; set; }
	}

	/// <summary>
	/// Events that can be subscribed.
	/// </summary>
	[Serializable]
	public enum Event
	{
		/// <summary>
		/// User phone busy state
		/// </summary>
		CallState,

		/// <summary>
		/// All kinds of presence.
		/// </summary>
		Presence,
	}
}
